package online.niuma.xiaocubao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import online.niuma.xiaocubao.mapper.ArticleBodyMapper;
import online.niuma.xiaocubao.mapper.ArticleMapper;
import online.niuma.xiaocubao.mapper.UserMapper;
import online.niuma.xiaocubao.pojo.entity.Article;
import online.niuma.xiaocubao.pojo.entity.ArticleBody;
import online.niuma.xiaocubao.pojo.entity.User;
import online.niuma.xiaocubao.pojo.params.AddArticleParam;
import online.niuma.xiaocubao.pojo.vo.ArticleContentVo;
import online.niuma.xiaocubao.pojo.vo.ArticleInfoVo;
import online.niuma.xiaocubao.pojo.vo.LoginUserVo;
import online.niuma.xiaocubao.pojo.vo.Result;
import online.niuma.xiaocubao.service.IArticleService;
import online.niuma.xiaocubao.service.ISendMailService;
import online.niuma.xiaocubao.service.IUserService;
import online.niuma.xiaocubao.utils.UserThreadLocal;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 一颗蛋50斤
 * @since 2022-11-12
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ArticleBodyMapper articleBodyMapper;
    @Resource
    private ISendMailService sendMailService;
    @Resource
    private IUserService userService;
    @Resource
    UserMapper userMapper;

    /**
     * 将前端传递过来的文章信息添加到数据库中
     *
     * @param addArticleParam 所要存储的文章信息
     * @return 存储成功与否的信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addArticle(AddArticleParam addArticleParam) {
        // 获取到登陆用户的信息
        LoginUserVo loginUserVo = UserThreadLocal.get();
        // 登陆用户 id
        Long userId = loginUserVo.getUserId();
        // 文章标题
        String articleTitle = addArticleParam.getArticleTitle();
        // 文章总结
        String articleSummary = addArticleParam.getArticleSummary();
        // 文章文本内容
        String bodyContent = addArticleParam.getBodyContent();
        // 文章 html 格式内容
        String bodyContentHtml = addArticleParam.getBodyContentHtml();

        // 创建文章实体对象
        Article article = new Article();
        // 添加标题
        article.setArticleTitle(articleTitle);
        // 添加文章总结信息
        article.setArticleSummary(articleSummary);
        // 添加作者id(登陆用户的id)
        article.setAuthorId(userId);
        // 插入文章的信息
        articleMapper.insert(article);

        // 实例化文章内容对象
        ArticleBody articleBody = new ArticleBody();
        // 添加文章的内容
        articleBody.setBodyContent(bodyContent);
        // 添加 html 格式的文章内容
        articleBody.setBodyContentHtml(bodyContentHtml);
        // 添加文章的id
        articleBody.setArticleId(article.getArticleId());
        // 添加文章内容
        articleBodyMapper.insert(articleBody);

        /*
        这里需要新建一个文章的实例对象对数据进行更新
        如果是直接调用上面创建的实例对象会无法对数据进行更新
        打印上面的实例对象显示的是一个内容地址
         */
        Article newArticle = new Article();
        newArticle.setArticleId(article.getArticleId());
        newArticle.setBodyId(articleBody.getBodyId());
        articleMapper.updateById(newArticle);

        // 添加文章后发送邮箱
        sendMailService.addArticleMail(loginUserVo, articleTitle);

        return Result.success("添加成功");
    }

    /**
     * 根据用户的信息查询文章的信息
     * 如果没有关联用户
     * 或者不是互相关联的
     * 只查询自己的所有文章信息
     * 如个有互相关联的用户，那么就查询两个人的文章信息
     *
     * @return 用户的文章信息
     */
    @Override
    public Result queryArticleInfoAllByUser() {
        // 获取登陆的用户
        LoginUserVo loginUserVo = UserThreadLocal.get();
        // 用户的账号
        String userAccount = loginUserVo.getUserAccount();
        // 关联用户的账号
        String userToaccount = loginUserVo.getUserToaccount();
        // 验证两个用户是不是互相关联的
        // 如果有值则表示两个账号是互相关联的
        String s = userService.checkMeRelationYou(userAccount, userToaccount);
        Map<String, ArrayList<Long>> map = new HashMap<>(1);
        ArrayList<Long> ids = new ArrayList<>();
        ids.add(loginUserVo.getUserId());
        // 如果两个用户是互相关联的
        if (!StringUtils.isBlank(s)) {
            // 查询关联用户的 id
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.select(User::getUserId);
            queryWrapper.eq(User::getUserAccount, userToaccount);
            User user = userMapper.selectOne(queryWrapper);
            // 将关联用户的 id 添加到集合中
            ids.add(user.getUserId());
        }
        map.put("ids", ids);
        // 查询文章的信息
        List<ArticleInfoVo> articleInfoVos = articleMapper.queryArticleInfoAllByUser(map);
        return Result.success(articleInfoVos);
    }

    /**
     * 根据文章id查询文章的内容
     *
     * @param articleId 文章id
     * @return 文章内容
     */
    @Override
    public Result getArticleById(Long articleId) {
        ArticleContentVo articleContentVo = articleMapper.queryArticleById(articleId);
        return Result.success(articleContentVo);
    }
}
